package in.hooray.core.utils;

/**
 * 短网址映射算法的理论（网上找到的资料）： 
	① 将长网址用md5算法生成32位签名串，分为4段,，每段8个字符； 
	② 对这4段循环处理，取每段的8个字符, 将他看成16进制字符串与0x3fffffff(30位1)的位与操作，超过30位的忽略处理； 
	③ 将每段得到的这30位又分成6段，每5位的数字作为字母表的索引取得特定字符，依次进行获得6位字符串； 
	④ 这样一个md5字符串可以获得4个6位串，取里面的任意一个就可作为这个长url的短url地址。 
 * @author darking
 *
 */
public class ShortUrlUtils {

	private static final String KEY = "hooray-mp";
	
	private static final String[] CHARS = new String[] { "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" ,
        "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" ,
        "u" , "v" , "w" , "x" , "y" , "z" , "0" , "1" , "2" , "3" , "4" , "5" ,
        "6" , "7" , "8" , "9" , "A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" ,
        "I" , "J" , "K" , "L" , "M" , "N" , "O" , "P" , "Q" , "R" , "S" , "T" ,
        "U" , "V" , "W" , "X" , "Y" , "Z"

	}; 
	
	public static final String ALPHABET = "23456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ-_";
    public static final int BASE = ALPHABET.length();

    public static String encode(int num) {
        StringBuilder str = new StringBuilder();
        while (num > 0) {
            str.insert(0, ALPHABET.charAt(num % BASE));
            num = num / BASE;
        }
        return str.toString();
    }

    public static int decode(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            num = num * BASE + ALPHABET.indexOf(str.charAt(i));
        }
        return num;
    }
	
	public static String[] shortUrl(String url) {
		// 对传入网址进行 MD5 加密
	    String hex = MyEncript.md5(KEY + url);
	    int hexLen = hex.length();   
        int subHexLen = hexLen / 8; 
        String[] shortShr = new String[4];
        for (int i = 0; i < subHexLen; i++) {   
            String outChars = "";   
            int j = i + 1;   
            String subHex = hex.substring(i * 8, j * 8);   
            long idx = Long.valueOf("3FFFFFFF", 16) & Long.valueOf(subHex, 16);   
               
            for (int k = 0; k < 6; k++) {   
                int index = (int) (Long.valueOf("0000003D", 16) & idx);   
                outChars += CHARS[index];   
                idx = idx >> 5;   
            }   
            shortShr[i] = outChars;   
        } 
        return shortShr;
	}
	
//	public static void main(String[] args) {
//		String url = "http://blog.csdn.net/xtu_xiaoxin/article/details/8796499";
//		StringBuilder sb = new StringBuilder();
//		for(String s : shortUrl(url)) {
//			sb.append(s);
//		}
//		System.out.println(sb);
//		System.out.println(encode(10000000));
//		System.out.println(encode(1000001));
//		System.out.println(decode("9zvW"));
//	}
}
